﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Core;
using Domain.MainModule.Entities;
using Domain.Core.Specification;
using Domain.MainModule.BillingInformations;

namespace Application.MainModule.BillingInformationManagement
{
    public class BillingInformationManagementService : IBillingInformationManagementService, IDisposable
    {
        #region members

        IBillingInformationRepository _billingInformationRepository;

        #endregion

        #region constructor

        public BillingInformationManagementService(IBillingInformationRepository billingInformationRepository)
        {
            if (billingInformationRepository == (IBillingInformationRepository)null)
            {
                throw new ArgumentNullException(Resources.Messages.exception_DependenciesAreNotInitialized);
            }

            _billingInformationRepository = billingInformationRepository;
        }

        #endregion

        #region IBillingInformationManagementService implementation

        public void AddBillingInformation(Domain.MainModule.Entities.BillingInformation billingInformation)
        {
            IUnitOfWork unitOfWork = _billingInformationRepository.UnitOfWork as IUnitOfWork;
            _billingInformationRepository.Add(billingInformation);
            unitOfWork.Commit();
        }

        public void ChangeBillingInformation(Domain.MainModule.Entities.BillingInformation billingInformation)
        {
            IUnitOfWork unitOfWork = _billingInformationRepository.UnitOfWork as IUnitOfWork;
            _billingInformationRepository.Modify(billingInformation);
            unitOfWork.CommitAndRefreshChanges();
        }

        public void RemoveBillingInformation(Domain.MainModule.Entities.BillingInformation billingInformation)
        {
            if (billingInformation == (BillingInformation)null)
            {
                throw new ArgumentNullException("billlingInformation");
            }

            IUnitOfWork unitOfWork = _billingInformationRepository.UnitOfWork as IUnitOfWork;
            _billingInformationRepository.Remove(billingInformation);
            unitOfWork.Commit();
        }

        public BillingInformation FindBillingInformationByIdSpecification(Guid billingInformationId)
        {
            BillingInformationBillingInformationIdSpecification spec = new BillingInformationBillingInformationIdSpecification(billingInformationId);
            return _billingInformationRepository.FindBillingInformation(spec);
        }

        public List<Domain.MainModule.Entities.BillingInformation> FindBillingInformationCompanyName(string companyName)
        {
            BillingInformationCompanyNameSpecification spec = new BillingInformationCompanyNameSpecification(companyName);
            return _billingInformationRepository.FindBillingInformations(spec).ToList<BillingInformation>();
        }

        public List<Domain.MainModule.Entities.BillingInformation> FindBillingInformationCUIT(string cuit)
        {
            BillingInformationCUITSpecification spec = new BillingInformationCUITSpecification(cuit);
            return _billingInformationRepository.FindBillingInformations(spec).ToList<BillingInformation>();
        }

        public List<Domain.MainModule.Entities.BillingInformation> FindBillingInformationGroupBranchId(Guid groupBranchId)
        {
            BillingInformationGroupBranchIdSpecification spec = new BillingInformationGroupBranchIdSpecification(groupBranchId);
            return _billingInformationRepository.FindBillingInformations(spec).ToList<BillingInformation>();
        }

        public List<Domain.MainModule.Entities.BillingInformation> FindPagedBillingInformation(int pageIndex, int pageCount)
        {
            if (pageIndex < 0)
            {
                throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex");
            }

            if (pageCount <= 0)
            {
                throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount");
            }

            Specification<BillingInformation> trueSpec = new TrueSpecification<BillingInformation>();

            return _billingInformationRepository.GetPagedElements(pageIndex, pageCount, c => c.BillingInformationId, trueSpec, true).ToList();
        }

        #endregion

        #region IDisposable

        /// <summary>
        /// Dispose associated context with this domain service
        /// </summary>
        public void Dispose()
        {
            if (_billingInformationRepository != null
                &&
                _billingInformationRepository.UnitOfWork != null)
            {
                _billingInformationRepository.UnitOfWork.Dispose();
            }
        }

        #endregion
    }
}
